package cn.jingyuan.owl.web.oauth2.client;

import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
import org.springframework.security.oauth2.common.AuthenticationScheme;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

/**
 * 请求工具类
 */
public class DefaultOAuth2RestTemplate extends RestTemplate {

    private DefaultOAuth2ResourceDetails oAuth2ResourceDetails;

    public DefaultOAuth2RestTemplate(DefaultOAuth2ResourceDetails oAuth2ResourceDetails) {
        Assert.notNull(oAuth2ResourceDetails, "oAuth2ResourceDetails must be not null");
        this.oAuth2ResourceDetails = oAuth2ResourceDetails;
    }

    public DefaultOAuth2ResourceDetails getOAuth2ResourceDetails() {
        return oAuth2ResourceDetails;
    }

    public void setOAuth2ResourceDetails(DefaultOAuth2ResourceDetails oAuth2ResourceDetails) {
        this.oAuth2ResourceDetails = oAuth2ResourceDetails;
    }

    /**
     * 构建 oauth2 client_credentials 方式请求
     */
    public OAuth2RestTemplate buildOAuth2ClientRequest() {
        String clientId = oAuth2ResourceDetails.getClientId();
        String clientSecret = oAuth2ResourceDetails.getClientSecret();
        String accessTokenUri = oAuth2ResourceDetails.getAccessTokenUri();

        return buildOAuth2ClientRequest(clientId, clientSecret, accessTokenUri);
    }

    /**
     * 构建 oauth2 client_credentials 方式请求
     *
     * @param clientId 客户端 id
     * @param clientSecret 客户端密钥
     * @param accessTokenUri 获取 token 地址
     */
    public OAuth2RestTemplate buildOAuth2ClientRequest(String clientId, String clientSecret, String accessTokenUri) {
        ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
        resource.setClientId(clientId);
        resource.setClientSecret(clientSecret);
        resource.setAccessTokenUri(accessTokenUri);

        return new OAuth2RestTemplate(resource);
    }

    /**
     * 构建 oauth2 password 方式请求
     *
     * @param username 用户名
     * @param password 密码
     */
    public OAuth2RestTemplate buildOAuth2PasswordRequest(String username, String password) {
        String clientId = oAuth2ResourceDetails.getClientId();
        String clientSecret = oAuth2ResourceDetails.getClientSecret();
        String accessTokenUri = oAuth2ResourceDetails.getAccessTokenUri();

        return buildOAuth2PasswordRequest(
            clientId,
            clientSecret,
            accessTokenUri,
            username,
            password
        );
    }

    /**
     * 构建 oauth2 password 方式请求
     *
     * @param clientId 客户端 id
     * @param clientSecret 客户端密钥
     * @param accessTokenUri 获取 token 地址
     * @param username 用户名
     * @param password 密码
     */
    public OAuth2RestTemplate buildOAuth2PasswordRequest(
        String clientId,
        String clientSecret,
        String accessTokenUri,
        String username,
        String password) {
        ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
        // resource.setId("");
        resource.setClientId(clientId);
        resource.setAccessTokenUri(accessTokenUri);
        // resource.setScope(new ArrayList<String>());
        resource.setClientSecret(clientSecret);
        resource.setAuthenticationScheme(AuthenticationScheme.form);

        resource.setUsername(username);
        resource.setPassword(password);

        return new OAuth2RestTemplate(resource);
    }

}
